package com.mall.module.system.controller;

import com.mall.common.enums.LogoutReasonEnum;
import com.mall.common.model.PageResult;
import com.mall.common.model.UserAuth;
import com.mall.common.result.Result;
import com.mall.common.util.SecurityUtils;
import com.mall.module.system.domain.dto.LoginDto;
import com.mall.module.system.domain.dto.RegisterDto;
import com.mall.module.system.domain.dto.UserQueryDto;
import com.mall.module.system.domain.entity.SysUser;
import com.mall.module.system.domain.vo.LoginVo;
import com.mall.module.system.domain.vo.MenuVO;
import com.mall.module.system.domain.vo.RegisterVo;
import com.mall.module.system.domain.vo.UserInfoVO;
import com.mall.module.system.mapper.SysDeptMapper;
import com.mall.module.system.service.SysMenuService;
import com.mall.module.system.service.SysPermissionService;
import com.mall.module.system.service.SysRoleService;
import com.mall.module.system.service.SysUserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.util.*;

@Api(tags = "系统用户管理接口")
@RestController
@RequestMapping("/api/admin")
@RequiredArgsConstructor
public class SysUserController {

    private final SysUserService sysUserService;
    private final SysRoleService sysRoleService;
    private final SysPermissionService sysPermissionService;
    private final SysMenuService sysMenuService;
    private final SysDeptMapper sysDeptMapper;

    // ==================== 认证相关接口 ====================
    @ApiOperation(value = "用户注册", notes = "注册新的系统用户")
    @PostMapping("/register")
    public Result<RegisterVo> register(@Valid @RequestBody RegisterDto registerDto) {
        return Result.success(sysUserService.register(registerDto));
    }

    @ApiOperation(value = "用户登录", notes = "系统用户登录")
    @PostMapping("/login")
    public Result<LoginVo> login(@Valid @RequestBody LoginDto loginDto) {
        return Result.success(sysUserService.login(loginDto));
    }

    @ApiOperation(value = "刷新Token", notes = "刷新当前用户的JWT Token")
    @PostMapping("/refresh-token")
    public Result<Map<String, String>> refreshToken(HttpServletRequest request) {
        String newToken = sysUserService.refreshToken(request);
        return Result.success(Collections.singletonMap("token", newToken));
    }

    @ApiOperation(value = "退出登录", notes = "用户退出登录")
    @PostMapping("/logout")
    public Result<String> logout(HttpServletRequest request) {
        return Result.success(sysUserService.logout(request));
    }

    // ==================== 用户管理接口 ====================
    @ApiOperation(value = "分页查询后台用户数据")
    @GetMapping("/list")
    public Result<PageResult<SysUser>> list(
        @RequestParam(defaultValue = "1") int pageNum,
        @RequestParam(defaultValue = "10") int pageSize,
        @RequestParam(required = false) UserQueryDto queryDto) {
        return Result.success(PageResult.restPage(sysUserService.list(pageNum, pageSize, queryDto)));
    }

    @ApiOperation(value = "更新用户信息")
    @PutMapping("/update/{userId}")
    public Result<Void> updateUser(@PathVariable Long userId, @RequestBody SysUser user) {
        sysUserService.updateUser(userId, user);
        return Result.success();
    }

    @ApiOperation(value = "更新用户密码")
    @PutMapping("/update-password/{userId}")
    public Result<Void> updatePassword(@PathVariable Long userId, @RequestParam String newPassword) {
        sysUserService.updatePassword(userId, newPassword);
        return Result.success();
    }

    @ApiOperation(value = "根据用户ID删除用户")
    @DeleteMapping("/delete/{userId}")
    public Result<Void> deleteUser(@PathVariable Long userId) {
        Long currentUserId = SecurityUtils.getCurrentUserId();
        if (currentUserId.equals(userId)) {
            return Result.error(401, "不能删除当前登录用户");
        }
        sysUserService.deleteUser(currentUserId, userId);
        return Result.success();
    }

    @ApiOperation(value = "根据用户ID查询用户信息")
    @GetMapping("/get/{userId}")
    public Result<SysUser> getUserById(@PathVariable Long userId) {
        return Result.success(sysUserService.getUserById(userId));
    }

    // ==================== 会话管理接口 ====================
    @ApiOperation(value = "强制用户下线", notes = "管理员强制指定用户下线")
    @PostMapping("/force-logout/{userId}")
    public Result<String> forceLogout(@PathVariable Long userId, @RequestParam String reason) {
        LogoutReasonEnum logoutReason = LogoutReasonEnum.getByCode(reason);
        return Result.success(sysUserService.forceLogout(userId, logoutReason));
    }

    @ApiOperation(value = "获取用户在线设备信息")
    @GetMapping("/online-devices/{userId}")
    public Result<List<Map<String, Object>>> getOnlineDevices(@PathVariable Long userId) {
        return Result.success(sysUserService.getUserOnlineDevices(userId));
    }

    @ApiOperation(value = "获取用户登出统计")
    @GetMapping("/logout-statistics/{userId}")
    public Result<Map<String, Object>> getLogoutStatistics(
        @PathVariable Long userId,
        @RequestParam(defaultValue = "7") int days) {
        return Result.success(sysUserService.getLogoutStatistics(userId, days));
    }

    // ==================== 当前用户接口 ====================
    @ApiOperation(value = "获取当前用户的信息")
    @GetMapping("/info")
    public Result<Map<String, Object>> info() {
        UserAuth userAuth = SecurityUtils.getCurrentUserAuth();
        Map<String, Object> data = new HashMap<>(2);
        data.put("userId", userAuth.getUserId());
        data.put("username", userAuth.getUsername());
        return Result.success(data);
    }

    @ApiOperation(value = "获取当前用户的在线设备信息")
    @GetMapping("/my-online-devices")
    public Result<List<Map<String, Object>>> getMyOnlineDevices() {
        return Result.success(
            sysUserService.getUserOnlineDevices(SecurityUtils.getCurrentUserId())
        );
    }

    @ApiOperation(value = "获取当前用户的登出统计")
    @GetMapping("/my-logout-statistics")
    public Result<Map<String, Object>> getMyLogoutStatistics(
        @RequestParam(defaultValue = "7") int days) {
        return Result.success(
            sysUserService.getLogoutStatistics(SecurityUtils.getCurrentUserId(), days)
        );
    }

    @ApiOperation(value = "获取当前登录用户详细信息", notes = "返回用户基本信息、角色和权限")
    @GetMapping("/getInfo")
    public Result<UserInfoVO> getInfo() {
        UserAuth userAuth = SecurityUtils.getCurrentUserAuth();
        Long userId = userAuth.getUserId();

        // 构建用户信息对象
        UserInfoVO userInfoVO = new UserInfoVO();
        buildUserInfo(userInfoVO, userId);

        // 获取角色和权限
        Set<String> roles = sysRoleService.getRolesByUserId(userId);
        Set<String> permissions = sysPermissionService.getPermissionsByUserId(userId);

        userInfoVO.setRoles(roles.isEmpty() ? null : new ArrayList<>(roles));
        userInfoVO.setPermissions(permissions.isEmpty() ? null : new ArrayList<>(permissions));

        return Result.success(userInfoVO);
    }

    @ApiOperation(value = "获取当前用户菜单路由")
    @GetMapping("/getRouters")
    public Result<List<MenuVO>> getRouters() {
        return Result.success(
            sysMenuService.getMenuTreeByUserId(SecurityUtils.getCurrentUserId())
        );
    }

    // ==================== 私有方法 ====================
    private void buildUserInfo(UserInfoVO userInfoVO, Long userId) {
        SysUser user = sysUserService.getUserById(userId);
        if (user == null) return;

        UserInfoVO.UserVO userVO = new UserInfoVO.UserVO();
        userVO.setId(user.getId());
        userVO.setUsername(user.getUsername());
        userVO.setNickname(user.getNickName());
        userVO.setAvatar(user.getIcon());
        userVO.setEmail(user.getEmail());
        userVO.setDeptId(user.getDeptId());

        // 部门 信息处理
        Optional.ofNullable(user.getDeptId())
            .map(sysDeptMapper::selectDeptById)
            .ifPresent(dept -> userVO.setDeptName(dept.getName()));

        userInfoVO.setUser(userVO);
    }
}